'''
Created on Jan 30, 2010

@author: oabalbin
'''
import numpy as np
from collections import deque
from collections import defaultdict


class parser():
    
    def microarray_exp_file(self, inputfile,outfile):
        """ 
        Reads agilent microarray composite files. The values are assumed to be fold change
        """
    
        header=False
        for line in inputfile:        
            line = line.strip('\n')
            fields = line.split('\t')
        
            # To skip headers, star reading samples in column 7 of the file
            if fields[0] == '#': 
                continue
            elif (fields[0] == 'Sample'):
                sampleName = fields[6:]
            elif fields[0] == 'Feature':
                header = True
                continue
            
            if header:   
                if fields[3]=='':
                    probeID = fields[2]
                    geneName='NULL'
                else:
                    probeID = fields[2]
                    geneName = fields[3]
                
                expValue = fields[6:]
                
                for exp,sample in zip(expValue,sampleName):
                    outfile.write(probeID+'\t'+geneName+'\t'+sample+'\t'+exp+'\n')
    
    
    def microarray_logexp_file(self, inputfile,outfile,mouse=False):
        """ 
        Reads agilent microarray composite files. The values are assumed to be log10 fold change
        """
        import signatures.db.gene_annotations as ga
        ga_conv = ga.gene_annotation("localhost", "oabalbin", "oscar", "gene_annotation")
        
        notfound=[]        
        header=False
        for line in inputfile:        
            line = line.strip('\n')
            fields = line.split('\t')
        
            # To skip headers, star reading samples in column 7 of the file
            if fields[0] == '#': 
                continue
            elif (fields[0] == 'Sample'):
                sampleName=[]
                for sp in fields[6:]:
                    if sp not in sampleName and sp != '':
                        sampleName.append(sp)
                    else:
                        continue
                #print sampleName
                
            
            elif fields[0] == 'Feature':
                header = True
                continue
            
            if header:   
                if fields[3]=='':
                    probeID = fields[2]
                    geneName='NULL'
                else:
                    probeID = fields[2]
                    geneName = fields[3]
                
                
                if mouse:
                    gene = ga_conv.translate_mouse2human([geneName])
                    if len(gene) > 0:
                        geneName = gene[0]
                    else:
                        notfound.append(geneName)
                        continue
                
                flength = len(fields[6:])
                fold_change_ind = range(2,flength,3)
                p_val_ind = range(1,flength,3)
                field_values = np.array(fields[6:])
                
                expVal = field_values[fold_change_ind]
                pvalue = field_values[p_val_ind]
                expValue0=[]
                pVal0=[]
                
                for e,p in zip(expVal,pvalue):
                    if e !='':
                        expValue0.append(float(e))
                        pVal0.append(float(p))
                    else:
                        expValue0.append(float(np.nan))
                        pVal0.append(float(np.nan))
                
                expValue = map(str,list(expValue0))
                pValues = map(str,list(pVal0))

                for exp,pval,sample in zip(expValue, pValues, sampleName):
                    outfile.write(probeID+'\t'+geneName+'\t'+sample+'\t'+exp+'\t'+pval+'\n')
        
        
        print notfound
        print len(notfound)

    
    
    
    def microarray_nci60_file(self, inputfile,outfile):
        """
        Reads the microarray file for the NCI60 panel data set. 
        This data set was normalized using microarray RMA method. 
        """
        
        header=False
        for line in inputfile:        
            line = line.strip('\n')
            fields = line.split('\t')
                    
            # To skip headers, star reading samples in column 7 of the file
            if fields[0] == '#': 
                continue
            elif (fields[0] == 'Sample'):
                sampleName = fields[4:] 
            elif fields[0] == 'Feature':
                header = True 
                continue
                
            
            if header:   
                if fields[2]=='':
                    probeID = fields[1]
                    geneName='NULL'
                else:
                    probeID = fields[1]
                    geneName = fields[2]
                
                expValue0 = fields[4:]
                # I choose to convert the unlog2 the value so I can uniformly applied log2 to all my matrix when normalizing the value
                expValue1 = np.power(2,np.array(map(float,expValue0))) 
                expValue = map(str,list(expValue1))
                
                for exp,sample in zip(expValue,sampleName):
                    outfile.write(probeID+'\t'+geneName+'\t'+sample+'\t'+exp+'\n')
    
                    
    def microarray_exp_softfile(self, inputfile,outfile,outfile2, outfile3, outfile4, outfile5, outfile6, outfile7, outfile8):
        """
        It reads a soft microarray expression file.
        """
        header=False
        read_patformtable=False
        geneHeader=False
        #data_begins=False
        sample_begins=False
        sampleHeader=False
        
        golup_training=[208029,208392]
        golub_test=[208404,208512]
        
        geneAnnotation=defaultdict()
        erg_status=defaultdict(deque)
        sampleslist=deque([])
        sampleslist_training=deque([])
        sampleslist_test=deque([])
        
        
        for line in inputfile:        
            line = line.strip('\n')
            fields = line.split('\t')
            #print fields
            
            if fields[0] == '!platform_table_begin':
                read_patformtable=True
            
            if fields[0] == '!platform_table_end':
                #data_begins=True
                read_patformtable=False
            
            
            if read_patformtable:
                if fields[0] == 'ID' and fields[1] == 'GeneID':
                    geneHeader=True
                    
            if read_patformtable and geneHeader:
                #ID    GeneID    REFSEQ    GB_ACC    Symbol    Description    OMIM    chromosome    map.location
                probeID, geneName = fields[0],fields[4]
                geneAnnotation[probeID] = geneName
            
            
            
            if geneHeader and not read_patformtable and not sample_begins:
                info = fields[0].split('=')
                info = [i.strip() for i in info]
                
                if info[0] == '^SAMPLE':
                    sampleName = info[1]
                    sp_number = int(sampleName.replace('GSM',''))
                    
                    if golup_training[0] <= sp_number <= golup_training[1]:
                        sampleslist_training.append(sampleName)
                    elif golub_test[0] <=  sp_number <=golub_test[1]:
                        sampleslist_test.append(sampleName)
                    
                    sampleslist.append(sampleName)
                                
                if info[0] == '!Sample_characteristics_ch1':
                    erg_fusion_info = info[1].split(':')
                    erg_fusion_info = [j.strip() for j in erg_fusion_info]
                    
                    if  erg_fusion_info[0] == 'FUSION' and erg_fusion_info[1] == 'NO':
                        erg_status[sampleName] = 'ETS-'
                    if  erg_fusion_info[0] == 'FUSION' and erg_fusion_info[1] == 'YES':
                        erg_status[sampleName] = 'ETS+'
                    if  erg_fusion_info[0] == 'FUSION' and erg_fusion_info[1] == '':
                        erg_status[sampleName] = 'None'
                        
                        
            if fields[0] == '!sample_table_begin':
                sample_begins = True
            
            if sample_begins:
                if fields[0] == 'ID_REF' and fields[1] == 'VALUE':
                    sampleHeader=True
                    continue
 
            if fields[0] == '!sample_table_end':
                sample_begins=False
                sampleHeader=False
                
            if sample_begins and sampleHeader:                
                ID_REF, value = fields[0], str(np.power(2,float(fields[1])))
                geneSymbol = geneAnnotation[ID_REF]
                outline = [ID_REF,geneSymbol,sampleName, value]
                outfile.write(",".join(outline).replace(',','\t')+'\n')
                
                
        # Print three more files with the sample information.
        for gen in geneAnnotation.values():
            outfile2.write(gen+'\n')
        
        # Print samplelist
        for sp in sampleslist:
            outfile3.write('0'+'\t'+sp+'\n')
            
        # Print samplelist training
        outfile7.write('Sample ID'+'\t'+'ETS'+'\n')
        for sp in sampleslist_training:
            outfile5.write('0'+'\t'+sp+'\n')
            outfile7.write(sp+'\t'+erg_status[sp]+'\n')
        
        # Print samplelist test
        outfile8.write('Sample ID'+'\t'+'ETS'+'\n')
        for sp in sampleslist_test:
            outfile6.write('0'+'\t'+sp+'\n')
            outfile8.write(sp+'\t'+erg_status[sp]+'\n')
        
        
        # Sample ERG fusion status
        outfile4.write('Sample ID'+'\t'+'ETS'+'\n')
        for sp, status in erg_status.iteritems():
            outfile4.write(sp+'\t'+status+'\n')
       
       
    def microarray_exp_geoMatrixfile(self, inputfile,annotationfile, outfile):
        """
        It reads a soft microarray expression file.
        """
        header=False
        read_patformtable=False
        geneHeader=False
        #data_begins=False
        sample_begins=False
        sampleHeader=False
                
        geneAnnotation=defaultdict()
        sampleslist=deque([])
        
        for line in annotationfile:        
            line = line.strip('\n')
            fields = line.split('\t')
            #print fields
            
            if fields[0] == '!platform_table_begin':
                read_patformtable=True
            
            if fields[0] == '!platform_table_end':
                #data_begins=True
                read_patformtable=False
                break
            
            if read_patformtable:
                if fields[0] == 'ID' and fields[1] == 'GeneID':
                    geneHeader=True
                    
            if read_patformtable and geneHeader:
                #ID    GeneID    REFSEQ    GB_ACC    Symbol    Description    OMIM    chromosome    map.location
                probeID, geneName = fields[0],fields[4]
                geneAnnotation[probeID] = geneName
        
        
        for line in inputfile:
            line = line.strip('\n')
            fields = line.split('\t')
            #print fields
              
            if fields[0] == '!series_matrix_table_begin':
                sample_begins = True
            
            if not sampleHeader and sample_begins:
                fields = [h.strip('\"') for h in fields]
                print fields  
                if fields[0] == 'ID_REF':
                    sampleslist = fields[1:]
                    sampleHeader=True
                    continue
 
            if fields[0] == '!series_matrix_table_end':
                sample_begins=False
                sampleHeader=False
                
            if sample_begins and sampleHeader:
                ID_REF=fields[0].strip('\"')
                geneName = geneAnnotation[ID_REF]
                expValue0=fields[1:]
                expValue1 = np.power(2,np.array(map(float,expValue0)))
                expValue = map(str,list(expValue1))
                
                for exp,sample in zip(expValue,sampleslist):
                    outfile.write(ID_REF+'\t'+geneName+'\t'+sample+'\t'+exp+'\n')
                
         

    def list_of_samples_status(self, inputfile):
        """
        It read a file with at least two columns. The first Column gives the sample name and the second one gives 
        a classification for the samples.
        """
        header=False
        samples={}
        pstatus = ['ETS+','ETS-','None']
        
        for st in  pstatus:
            samples[st] = [] 
        
        for line in inputfile:        
            line = line.strip('\n')
            fields = line.split('\t')
            
            # To skip headers, star reading samples in column 7 of the file
            if fields[0] == '#': 
                continue
            elif (fields[0] == 'Sample ID'):
                header = True
                continue
            
            if header:   
                if fields[0]=='':
                    sampleName='NULL'
                    status='NULL'
                else:
                    sampleName = fields[0]
                    spst=fields[1]
                    
                    if spst in ('ERG+','ETV1+','ETV5+, ETS+'):
                        status='ETS+'
                    elif spst in ('ETS-'):
                        status='ETS-'
                    else:
                        status='None'
                    
                samples[status].append(sampleName)
            
            
        return samples
    
           
                 
    def list_of_names(self, inputfile):
        
        genlist=deque()
        for line in inputfile:        
            line = line.strip('\n')
            fields = line.split('\t')
        
            # To skip headers, star reading samples in column 7 of the file
            if fields[0][0] == '#': 
                continue                             
            if fields[0]=='':
                continue
            else:
                genlist.append(fields[0])
        
        return genlist
    
    def list_of_names_in_line(self, inputfile):     

        genlist=deque()
        for line in inputfile:        
            line = line.strip('\n')
            genlist = line.split('\t')
            
        '''
        if '-' in  genlist:
            i = genlist.index('-')
            genlist.pop([i])
        '''
        
        return genlist
    
    def list_of_names_group(self, inputfile):     

        #samplelist= defaultdict(list)
        samplelist=deque([])
        samplelist2=deque([])
        samplegroups=[]

        for line in inputfile:
            line = line.strip('\n')
            if line=='' or line.startswith('#'):
                continue
            
            fields = line.split('\t')
            samplelist.append((fields[0], fields[1]))
            samplelist2.append(fields[1])
            samplegroups.append(fields[0])
            
            
        g = len(set(samplegroups))
        N = len(samplelist)
        H = np.zeros((N,g))
        
        for i,spg in enumerate(samplelist):
            j = int(spg[0])
            H[i,j] = 1
                
        return samplelist2, H

    

'''
myp = parser()
inputfile = open('/exds/users/oabalbin/projects/microarray_data/golub_expression_matrices/GSE8402_series_matrix-1.txt')
annotationfile= open('/exds/users/oabalbin/projects/microarray_data/golub_expression_matrices/soft_files/GPL5474_family.txt')
outfile ='/exds/users/oabalbin/projects/microarray_data/golub_expression_matrices/GSE8402_series.db'
outfile2 ='/exds/users/oabalbin/projects/microarray_data/golub_expression_matrices/GPL5474_family_genelist'
outfile3 ='/exds/users/oabalbin/projects/microarray_data/golub_expression_matrices/GPL5474_family_samplelist'
outfile4 ='/exds/users/oabalbin/projects/microarray_data/golub_expression_matrices/GPL5474_family_samplelist_status'
#myp.microarray_exp_softfile(inputfile,open(outfile,'w'), open(outfile2,'w'), open(outfile3,'w'), open(outfile4,'w'))
myp.microarray_exp_geoMatrixfile(inputfile,annotationfile, outfile)
#samples = myp.list_of_names_group(open(inputfile))
#print samples
'''